البنى (Structures) والمعدودات (Enums) في لغة سي شارب #C: دراسة مفصلة وشاملة
تعتبر لغة سي شارب (#C) من أبرز لغات البرمجة التي تجمع بين سهولة الاستخدام والقدرة على بناء تطبيقات متقدمة ومتنوعة في مختلف المجالات، من التطبيقات المكتبية إلى تطبيقات الويب والخدمات السحابية. من بين الميزات الأساسية في هذه اللغة، تأتي البنى (Structures) والمعدودات (Enums) كعناصر مهمة للتحكم في نوع البيانات وتنظيمها بطريقة تسمح ببرمجة أكثر وضوحًا وكفاءة. في هذا المقال سيتم تناول هذين المفهومين بالتفصيل، مع شرح دقيق لكيفية تعريفهما واستخدامهما، بالإضافة إلى مقارنة مع أنواع البيانات الأخرى، والتطبيقات العملية التي تستفيد منهما، مع التركيز على القواعد التقنية والممارسات الأفضل عند العمل بهما.
أولاً: البنى (Structures) في لغة سي شارب
مفهوم البنية Structure
البنية (Structure) في لغة سي شارب هي نوع قيمة (Value Type) مخصص يتيح للمبرمج تجميع عدة متغيرات ذات أنواع مختلفة ضمن وحدة واحدة تسمى “بنية”. تم تصميم البنى لتخزين بيانات ذات صلة معًا بشكل منطقي، وتختلف عن الكائنات (Objects) التي تعتبر نوع مرجعي (Reference Type) في #C.
يمكن اعتبار البنية كنوع بيانات مركب يمكنه احتواء حقول (Fields)، وخصائص (Properties)، وطرق (Methods)، ومُعاملات (Operators)، وحتى أحداث (Events)، لكن مع بعض القيود مقارنة بالكائنات.
تعريف البنى
تعريف بنية يتم باستخدام الكلمة المفتاحية struct، تليها اسم البنية، ثم الكتل التي تحتوي على أعضاء البنية.
csharpstruct Point
{
public int X;
public int Y;
public void Display()
{
Console.WriteLine($"X: {X}, Y: {Y}");
}
}
في هذا المثال، تم تعريف بنية Point تحتوي على متغيرين من النوع int هما X و Y، مع طريقة تقوم بعرض قيم المتغيرات.
خصائص البنى في #C
-
نوع قيمة (Value Type): يتم تخزين بيانات البنية مباشرة في الذاكرة وليس عبر مرجع، وبالتالي عند تمرير بنية إلى دالة يتم تمرير نسخة منها.
-
لا تدعم الوراثة: لا يمكن لبنية أن ترث من بنية أخرى أو من كلاس (Class)، ولكن يمكنها تنفيذ الواجهات (Interfaces).
-
تضمين طرق وأحداث وخصائص: البنى يمكن أن تحتوي على وظائف، خصائص، مُعاملات، وأحداث.
-
إنشاء كائنات بدون استخدام new: يمكن إنشاء متغير من نوع بنية بدون استدعاء
new، لكن هذا يجعل أعضاء البنية غير مهيئين. -
توفير الأداء: لأنها أنواع قيمة، لا يتم تخصيصها على كومة الذاكرة (Heap) مما يجعلها أسرع وأقل استهلاكًا للذاكرة في بعض الحالات.
تهيئة البنى
عند إنشاء بنية، يمكن تهيئتها باستخدام معامل البناء (Constructor) الخاص بالبنى، الذي يجب أن يهيئ جميع الأعضاء قبل الانتهاء.
csharpstruct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
الفرق بين البنى والكائنات
| الخاصية | البنى (Struct) | الكائنات (Class) |
|---|---|---|
| نوع البيانات | قيمة (Value Type) | مرجعية (Reference Type) |
| مكان التخزين | المكدس (Stack) | الكومة (Heap) |
| الوراثة | لا تدعم الوراثة | تدعم الوراثة |
| التهيئة | تحتاج إلى تهيئة صريحة | يمكن تهيئتها افتراضياً |
| الأداء | أسرع في العمليات الصغيرة | أبطأ بسبب التعامل مع المرجع |
استخدامات البنى
-
تخزين البيانات البسيطة التي تمثل كائنات صغيرة الحجم.
-
الاستخدام في البرمجة الرسومية مثل تمثيل النقاط والأشكال.
-
تحسين الأداء في الحالات التي تتطلب عمليات سريعة مع كميات كبيرة من البيانات الصغيرة.
-
عند الحاجة إلى نوع بيانات لا يتطلب الوراثة أو سلوكاً معقداً.
مثال عملي على بنية مع خصائص وطرق
csharpstruct Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
public int Area()
{
return Width * Height;
}
public override string ToString()
{
return $"Rectangle: Width={Width}, Height={Height}, Area={Area()}";
}
}
ثانياً: المعدودات (Enums) في لغة سي شارب
مفهوم المعدود Enum
المعدود (Enumeration) هو نوع بيانات مخصص يستخدم لتعريف مجموعة من القيم الثابتة ذات معنى منطقي متسلسل أو غير متسلسل، وغالبًا ما تستخدم لتمثيل حالات أو خيارات محددة في البرنامج. هذا يساعد في جعل الكود أكثر وضوحًا وأسهل قراءة، بدلاً من استخدام الأعداد الصحيحة أو السلاسل النصية العادية.
تعريف المعدودات
تعريف المعدود يتم باستخدام الكلمة المفتاحية enum متبوعة باسم المعدود، ثم قائمة القيم:
csharpenum DayOfWeek
{
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
القيم الافتراضية
كل عنصر في المعدود يمثل قيمة صحيحة تبدأ من 0 بشكل افتراضي، ولكن يمكن تخصيص هذه القيم:
csharpenum StatusCode
{
Success = 1,
Warning = 2,
Error = 4,
Critical = 8
}
استخدام المعدودات في البرمجة
-
تمثيل الحالات (State Representation) مثل حالات الطلب (معلق، مكتمل، ملغي).
-
استخدامات القيم الثنائية أو المجموعات (bit flags) عند تحديد الأذونات.
-
تحسين قراءة الكود عن طريق استخدام أسماء دلالية بدلاً من الأرقام.
خصائص المعدودات في #C
-
النوع الأساسي الافتراضي هو
int، ولكن يمكن تغييره لأنواع عددية أخرى مثلbyte,short,long، وغيرها. -
يمكن للمعدود تنفيذ واجهات (interfaces) ولكن لا يمكنه توارث أنواع أخرى.
-
يمكن تحويل قيمة المعدود إلى رقم صحيح والعكس باستخدام عمليات التحويل.
مثال على تعيين النوع الأساسي لمعدود
csharpenum Permissions : byte
{
Read = 1,
Write = 2,
Execute = 4,
Delete = 8
}
التعامل مع القيم العددية
يمكن تحويل قيمة المعدود إلى قيمتها الرقمية:
csharpDayOfWeek today = DayOfWeek.Wednesday;
int dayValue = (int)today; // القيمة ستكون 3
استخدامات متقدمة: أذونات بنظام الـ Flags
يمكن تمييز المعدودات باستخدام السمة [Flags] لتسهيل التعامل مع مجموعات من القيم.
csharp[Flags]
enum FileAccess
{
None = 0,
Read = 1,
Write = 2,
Execute = 4,
ReadWrite = Read | Write
}
في هذا المثال، يمكن تخزين أكثر من صلاحية واحدة في متغير واحد.
الفروقات الأساسية بين البنى والمعدودات
| الخاصية | البنى (Struct) | المعدودات (Enum) |
|---|---|---|
| نوع البيانات | نوع قيمة مخصص لتجميع بيانات متعددة | نوع قيمة يعرّف مجموعة ثابتة من القيم المسماة |
| إمكانية التوسعة | يمكن أن يحتوي على حقول وطرق وخصائص وأحداث | يحتوي فقط على مجموعة من الثوابت العددية |
| الاستخدام | تخزين بيانات معقدة أو مركبة | تمثيل الحالات أو القيم الثابتة أو الخيارات |
| النوع الأساسي الافتراضي | غير محدد، حسب أنواع الحقول | int بشكل افتراضي، يمكن تغييره |
| دعم الوراثة | لا يدعم الوراثة | لا يدعم الوراثة |
قواعد وممارسات مهمة عند استخدام البنى والمعدودات
1. اختيار النوع المناسب
عند الحاجة إلى تجميع بيانات متعددة ذات أنواع مختلفة معًا، يفضل استخدام البنى، بينما إذا كان الهدف هو تمثيل مجموعة ثابتة من القيم المحددة مسبقًا، فيكون المعدود هو الحل الأمثل.
2. الانتباه إلى حجم البيانات
نظرًا لأن البنى تُعامل كنُسخ، فإن استخدامها مع بيانات كبيرة الحجم قد يسبب انخفاضًا في الأداء بسبب نسخ البيانات المتكرر، لذا يُفضل استخدامها مع مجموعات بيانات صغيرة.
3. استخدام التهيئة الصحيحة
يجب الحرص على تهيئة جميع أعضاء البنى قبل استخدامها، سواء عبر منشئ مخصص أو تعيين قيم افتراضية.
4. استخدام سمة [Flags] مع المعدودات التي تمثل مجموعات من القيم
عند استخدام المعدودات في تمثيل أذونات أو خيارات متعددة يمكن تفعيلها معًا، فمن المهم تمييز المعدود بهذه السمة لضمان عمل العمليات المنطقية بشكل صحيح.
5. تجنب استخدام البنى لتعقيد العمليات
في حال كانت البيانات أو العمليات التي تجرى مع النوع تتطلب سلوكًا معقدًا أو وراثة، يفضل تحويل البنية إلى كلاس.
أمثلة تطبيقية متقدمة
مثال 1: بنية تحتوي على خصائص، منشئ، وطريقة حساب
csharpstruct Circle
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public double CalculateArea()
{
return Math.PI * Radius * Radius;
}
}
مثال 2: استخدام المعدود مع Flags للتحكم في أذونات المستخدم
csharp[Flags]
enum UserPermissions
{
None = 0,
View = 1,
Edit = 2,
Delete = 4,
Admin = 8
}
class Program
{
static void Main()
{
UserPermissions permissions = UserPermissions.View | UserPermissions.Edit;
bool canEdit = (permissions & UserPermissions.Edit) == UserPermissions.Edit;
Console.WriteLine($"Can edit: {canEdit}"); // سيطبع: Can edit: True
}
}
الجدول المقارن بين البنى والمعدودات
| الميزة | البنى (Struct) | المعدودات (Enum) |
|---|---|---|
| نوع البيانات | نوع قيمة مخصص لتجميع بيانات متعددة | نوع قيمة لتعريف مجموعة من القيم الثابتة |
| إمكانية احتواء الوظائف | يمكن احتواء خصائص، طرق، مُعاملات، أحداث | لا يمكن احتواء وظائف، فقط ثوابت |
| إمكانية الوراثة | لا يمكن الوراثة | لا يمكن الوراثة |
| التخزين | يخزن في الذاكرة مباشرة (Stack) | يخزن كنوع قيمة رقمي (عادة int) |
| الأداء | أفضل مع البيانات الصغيرة | سريع جدًا بسبب بساطة النوع |
| الاستخدام الأمثل | تمثيل بيانات مركبة كالنقاط، المستطيلات | تمثيل الحالات، الخيارات، الأذونات |
| التهيئة | يجب تهيئة الأعضاء قبل الاستخدام | يمكن استخدام القيم الافتراضية أو المعينة |
الخاتمة التقنية
تشكل البنى والمعدودات حجر الأساس في التعامل مع البيانات ضمن بيئة لغة سي شارب. حيث توفر البنى طريقة فعالة ومرنة لتجميع البيانات ذات الصلة ضمن وحدة واحدة تحمل قيمًا مختلفة الأنواع، مع إمكانيات تضيف وظائف وأحداث مما يجعلها أداة قوية لبناء بيانات منظمة ذات أداء عالٍ في البيئات التي تتطلب السرعة وكفاءة الذاكرة. بالمقابل، تمنح المعدودات طريقة منظمة وواضحة لتعريف مجموعات القيم الثابتة التي تعبر عن حالات أو خيارات محددة، مما يحسن من قابلية قراءة وصيانة الكود.
فهم كيفية استخدام كل منهما بشكل صحيح يعزز من جودة الكود، وفعالية التطبيق، ويقلل من الأخطاء البرمجية التي قد تنجم عن استخدام أنواع بيانات غير مناسبة. لذا، تمثل البنى والمعدودات أدوات لا غنى عنها في ترسانة أي مبرمج سي شارب يسعى لتطوير برمجيات متينة وقابلة للتوسع.
المصادر والمراجع
-
Microsoft Docs – Structs (C# Programming Guide)
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/structs -
Microsoft Docs – Enumerations (C# Programming Guide)
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum
هذا المقال يقدم شرحًا موسعًا علميًا وتقنيًا حول البنى والمعدودات في لغة #C، ليشكل مرجعًا متكاملاً يمكن الاعتماد عليه في الاستخدام العملي والتعليمي.

